/* License Notice:
**
** This program is free software: you can redistribute it and/or modify
**    it under the terms of the GNU General Public License as published by
**    the Free Software Foundation, either version 3 of the License, or
**    (at your option) any later version.
** This program is distributed in the hope that it will be useful,
**   but WITHOUT ANY WARRANTY; without even the implied warranty of
**   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
**   GNU General Public License for more details.
** You should have received a copy of the GNU General Public License
**   along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

/**
 * @file player.hpp
 * @author TooOld2Rock'nRoll
 * @date 2023/02/07
 * @brief Implements the framework for players management for the ArcadeFighter library.
 *
 * @todo In mapInput(), if we mark all three states to the same event, is it necessary? Should we support different actions for each state?
 * @todo In processEvents(), only send input to the puppet if action buttons, ignore start etc...
 * @todo As things get more complex, try to transform this class into a interface (update and draw can be = 0)
 * @todo Draw does not require time stamp, remove it.
 */
#ifndef _PLAYER_HPP_
#define _PLAYER_HPP_

/*---- Includes ----*/
#include <stdexcept>

#include "event_manager.hpp"
#include "character.hpp"



/**
 * @brief Player class for the ArcadeFighter library.
 *
 * This class offers a basic implementation for a Player (human or otherwise).<br>
 * You are encouraged to extend this class for your games if required.
 */
class Player
{
    private:


    protected:
        EventManager *evMngInstance = nullptr;///< A pointer to the EventManager singleton.
        listenerID_t lsID = 0;///< Listener ID to access the EventManager functionalities.
        ///List of expected input events, each key has 3 possible states.
        const EventManager::event_s *ap_action_input[controller_button_map_t::_button_max * key_state::_key_state_max];
        ///The action input array size, it should not change during execution.
        const unsigned u_action_array_size = controller_button_map_t::_button_max * key_state::_key_state_max;

        Character *p_puppet = nullptr;///< Pointer to the Character this Player is currently playing with.


    public:
        Player ();
        virtual ~Player ();

        //we need specific methods to register events for different interfaces since they must be
        //   "translated" to a more standard mapping (which for us is a console "controller")
        int mapInput (controller_button_map_t in, SDL_Scancode key, SDL_Keymod mod = KMOD_NONE);
        /* add other input sources as they are implemented */

        /** @brief Sets the character used by this player. */
        void setCharacter (Character *puppet) { this->p_puppet = puppet; }
        /** @brief Gets the character currently being used by this player. */
        Character* getCharacter () const { return this->p_puppet; }


        /*--- Player Information ---*/
        virtual void processEvents (double delta_t);
        virtual void update (double delta_t);
        virtual void draw (double delta_t);
};//END Player

#endif //_PLAYER_HPP_

